package com.ics.cmsadmin.modules.basic.service.impl;

import com.ics.cmsadmin.frame.core.annotation.CacheDbMember;
import com.ics.cmsadmin.frame.core.annotation.ClearDbMember;
import com.ics.cmsadmin.frame.core.bean.PageBean;
import com.ics.cmsadmin.frame.core.bean.PageResult;
import com.ics.cmsadmin.frame.core.enums.ApiResultEnum;
import com.ics.cmsadmin.frame.core.enums.CacheGroupEnum;
import com.ics.cmsadmin.frame.core.exception.CmsException;
import com.ics.cmsadmin.modules.basic.bean.*;
import com.ics.cmsadmin.modules.basic.dao.AnswersDao;
import com.ics.cmsadmin.modules.basic.dao.ProblemDao;
import com.ics.cmsadmin.modules.basic.dao.ProblemSetDao;
import com.ics.cmsadmin.modules.basic.dao.TipsDao;
import com.ics.cmsadmin.modules.basic.service.ProblemService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by lvsw on 2018-09-06.
 */
@Service
public class ProblemServiceImpl implements ProblemService {
    @Resource
    private ProblemDao problemDao;
    @Resource
    private ProblemSetDao problemSetDao;
    @Resource
    private AnswersDao answersDao;
    @Resource
    private TipsDao tipsDao;

    @CacheDbMember(returnClass = ProblemBean.class, group = CacheGroupEnum.CACHE_PROBLEM_GROUP)
    @Override
    public ProblemBean queryById(String id) {
        if (StringUtils.isBlank(id)){
            return null;
        }
        return problemDao.queryById(id);
    }

    @CacheDbMember(returnClass = ProblemBean.class, group = CacheGroupEnum.CACHE_PROBLEM_GROUP)
    @Override
    public PageResult<ProblemBean> list(ProblemBean bean, PageBean page) {
        long count = problemDao.count(bean);
        if (count == 0){
            return new PageResult<>();
        }
        page = page == null ? new PageBean() : page;
        return PageResult.getPage(count, problemDao.list(bean, page));
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_PROBLEM_GROUP)
    @Override
    public boolean update(String id, ProblemBean bean) {
        if (StringUtils.isBlank(id) || bean == null || queryById(id) == null){
            throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "参数有误");
        }
        return problemDao.update(id, bean) == 1;
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_PROBLEM_GROUP)
    @Override
    public boolean insertProblem(ProblemBean problemBean, List<AnswersBean> answersBeans, List<TipsBean> tipsBeans) {
        validatedData(problemBean, answersBeans);
        ProblemSetBean problemSetBean = problemSetDao.queryById(problemBean.getProblemSetId());
        if (problemSetBean == null){
            throw new CmsException(ApiResultEnum.INSERT_TABLE_ITEM_FAIL, "找不到对应题集信息");
        }
        problemDao.insert(problemBean);
        answersDao.batchInsert(answersBeans, problemBean.getProblemId());
        dealWithTips(tipsBeans, problemBean.getProblemId());
        return true;
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_PROBLEM_GROUP)
    @Override
    public boolean updateProblem(ProblemBean problemBean, List<AnswersBean> answersBeans, List<TipsBean> tipsBeans, String problemId) {
        validatedData(problemBean, answersBeans);
        if (queryById(problemId) == null){
            throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "查不到对应的问题");
        }
        update(problemId, problemBean);
        answersDao.deleteByProblemId(problemId);
        tipsDao.deleteByProblemId(problemId);
        answersDao.batchInsert(answersBeans, problemBean.getProblemId());
        dealWithTips(tipsBeans, problemId);
        return true;
    }

    private void dealWithTips(List<TipsBean> tipsBeans, String problemId) {
        if (CollectionUtils.isNotEmpty(tipsBeans)){
            tipsBeans.stream().forEach(item -> {
                if (StringUtils.isNoneBlank(item.getLevelNode())) {
                    String[] split = item.getLevelNode().split(",");
                    item.setPointId(split[split.length - 1]);
                }
            });
            tipsDao.batchInsert(tipsBeans, problemId);
        }
    }

    private void validatedData(ProblemBean problemBean, List<AnswersBean> answersBeans) {
        if (problemBean == null || CollectionUtils.isEmpty(answersBeans)) {
            throw new CmsException(ApiResultEnum.VALIDATE_ERROR, "上传数据为空");
        }
        if (StringUtils.isBlank(problemBean.getTitle()) || StringUtils.isBlank(problemBean.getContent()) || StringUtils.isBlank(problemBean.getOrderNo())) {
            throw new CmsException(ApiResultEnum.VALIDATE_ERROR, "问题标题/内容/排序为空");
        }
        if (!StringUtils.isNumeric(problemBean.getOrderNo())){
            throw new CmsException(ApiResultEnum.VALIDATE_ERROR, "排序必须为数字");
        }
        if (answersBeans.stream().noneMatch(AnswersBean::isCorrect)){
            throw new CmsException(ApiResultEnum.VALIDATE_ERROR, "至少要包含一个正确答案");
        }
        if(answersBeans.stream().anyMatch(item -> StringUtils.isBlank(item.getContent()))){
            throw new CmsException(ApiResultEnum.VALIDATE_ERROR, "答案内容不能为空");
        }
        answersBeans.stream().forEach(item -> item.setIsCorrect(item.isCorrect() ? "1" : "0"));
    }

    @CacheDbMember(returnClass = ProblemDto.class, group = CacheGroupEnum.CACHE_PROBLEM_GROUP)
    @Override
    public ProblemDto queryDetailsByProblemId(String problemId) {
        ProblemBean problemBean = queryById(problemId);
        List<AnswersBean> answersBeans = answersDao.queryByProblemId(problemId);
        List<TipsBean> tipsBeans = tipsDao.queryByProblemId(problemId);
        return ProblemDto.builder().problem(problemBean).answers(answersBeans).tips(tipsBeans).build();
    }

    @CacheDbMember(returnClass = ProblemDto.class, group = CacheGroupEnum.CACHE_PROBLEM_GROUP)
    @Override
    public List<ProblemDto> queryDetailsByProblemSetId(String problemSetId) {
        List<ProblemBean> problemBeans = problemDao.list(ProblemBean.builder().problemSetId(problemSetId).build(), new PageBean(1, Integer.MAX_VALUE));
        if (CollectionUtils.isEmpty(problemBeans)){
            return null;
        }
        return problemBeans.stream().map(item -> this.queryDetailsByProblemId(item.getProblemId())).collect(Collectors.toList());
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_PROBLEM_GROUP)
    @Override
    public boolean delete(String problemId) {
        problemDao.delete(problemId);
        answersDao.deleteByProblemId(problemId);
        tipsDao.deleteByProblemId(problemId);
        return true;
    }
}
